/**
 * 描述：公共编辑页面业务逻辑基础类
 * 路径：/framework/schema/component/EditableComponent.js
 * 作者：王鑫
 * 时间：2019-12-18
 */

import { ViewEditable } from './property/ViewEditable';
export default {
  props: {
    editable: {
      type: ViewEditable,
      default: () => new ViewEditable()
    },
    visible: {
      type: Boolean,
      default: false
    },
    params: {
      type: Object
    },
    options: {
      type: Object,
      default: () => {
        return {
          name: undefined,
          data: {}
        }
      }
    }
  },
  data() {
    return {
      name: "",
      show: false,
      forms: {},
      internal: {
        isNew: false,
        dataMounted: false,
        backupForms: null
      }
    }
  },
  computed: {
    title() {
      let name = this.editable.name || this.name;
      if (this.internal.isNew) {
        return `新增 ${name}`;
      } else {
        return `修改 ${name}`;
      }
    }
  },
  watch: {
    'editable.visible'(value) {
      value && this.initDispatch();
      this.show = value;
    },
    visible(value) {
      this.editable.visible = value;
    },
    params(value) {
      this.editable.params = value;
    },
    options(value) {
      this.editable.options = value;
    }
  },
  methods: {
    validate(fn) {
      this.$refs.forms.validate(valid => {
        valid && fn && fn();
      });
    },

    execute() {
      let view = this.$children[0];
      view.loading = true;
      const forms = { ...this.editable.data, ...this.forms }
      let params = this.packageParams(forms);
      let promise = null;
      if (this.internal.isNew) {
        promise = this.getCreate(params);
      } else {
        promise = this.getModify(params);
      }
      if (promise) {
        promise
          .then(() => {
            this.$Notice.success({
              title: "通知",
              desc: `${this.title}成功`
            });
            this.onSuccess();
          })
          .catch(this.$Error)
          .finally(() => { view.loading = false });
      } else {
        this.$Error({ ret: -1, title: "代码错误", desc: "接口不存在", });
        view.loading = false
      }
    },

    // #region Dispatch
    initDispatch() {
      this.$nextTick(() => {
        this.initData();
        this.initView();
      });
    },

    initView() {
      if (this.editable.params) {
        this.internal.isNew = false;
      } else {
        this.internal.isNew = true;
        this.$nextTick(() => { this.onReset() });
      }
    },

    initData() {
      const promises = [];
      // 处理获取详情数据
      if (this.editable.params) {
        promises.push(this.getDetail(this.editable.params));
      }
      // 处理首次加载页面
      const handleOnLoad = new Promise((resolve) => {
        const raiseResolve = () => {
          if (!this.internal.backupForms) {
            this.internal.backupForms = { ...this.forms };
          }
          resolve({ data: { ...this.internal.backupForms } });
        };
        // 装载数据：该方法仅执行一次
        if (this.internal.dataMounted) {
          raiseResolve();
        } else {
          this.internal.dataMounted = true;
          let res = this.onLoad();
          if (res) {
            res.then(raiseResolve);
          } else {
            raiseResolve();
          }
        }
      });
      promises.push(handleOnLoad);
      // 处理打开页面
      const handleOnShow = new Promise((resolve) => {
        let res = this.onShow();
        if (res) {
          res.then(resolve);
        } else {
          resolve();
        }
      });
      promises.push(handleOnShow);

      Promise.all(promises)
        .then(res => {
          if (Array.isArray(res) && res.length > 0 && res[0]) {
            this.unPackageForms(res[0].data);
          }
        })
        .catch(this.$Error);
    },
    // #endregion

    // #region Event
    /**
     * 仅在页面加载时执行一次
     * @virtual
     * @return {void|Promise}
     */
    onLoad() {
      console.warn(`未重写 onLoad 事件，本提示对功能没有任何影响`);
    },
    /**
     * 每次页面打开时都会执行
     * @virtual
     * @return {void|Promise}
     */
    onShow() {
      console.warn(`未重写 onShow 事件，本提示对功能没有任何影响`);
    },

    onSubmit() {
      this.validate(() => this.execute());
    },

    onReset() { this.$refs.forms.resetFields(); },

    onSuccess() { this.$emit("success"); },
    // #endregion

    // #region interface
    /**
     * 解包（每次打开窗口都会触发该方法）
     * @virtual
     */
    unPackageForms(data) {
      this.forms = { ...data };
    },
    /**
     * 打包参数
     * @virtual
     *  -该方法内部可进行自定义参数验证
     *  -若验证失败可通过返回false来中断提交过程
     * @param {JSON} forms 请求时传递的参数
     * @returns {JSON}
     */
    packageParams(forms) {
      return { ...forms };
    },
    /**
     * 返回执行获取详情内容的Promise
     * @virtual
     * @param {JSON} params 请求时传递的参数
     * @returns {Promise}
     */
    getDetail(params) { return new Promise(); },
    /**
     * 返回执行新增内容的Promise
     * @virtual
     * @param {JSON} params 请求时传递的参数
     * @returns {Promise}
     */
    getCreate(params) { return new Promise(); },
    /**
     * 返回执行修改内容的Promise
     * @virtual
     * @param {JSON} params 请求时传递的参数
     * @returns {Promise}
     */
    getModify(params) { return new Promise(); }
    // #endregion
  }
}
